﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UofCASE.AgileProductLinerDSL.Nant.Tasks.Models
{
    public class CompositeEnumerator<T> : IEnumerator<T>
    {
        IEnumerator<IEnumerable<T>> iters;
        IEnumerator<T> current;
        bool firstMove;

        public CompositeEnumerator(IEnumerator<IEnumerable<T>> iters)
        {
            this.iters = iters;
            current = null;
            firstMove = true;
        }

        public T Current
        {
            get {
                if (current != null)
                    return current.Current;
                else
                    return default(T);
            }
        }

        public void Dispose()
        {
            iters.Dispose();
        }

        public bool MoveNext()
        {
            // first call to both meta and [0]
            if (firstMove)
            {
                firstMove = false;
                if (iters.MoveNext())
                {
                    current = iters.Current.GetEnumerator();
                    return generalMoveNext();
                }
                return false;
            }
            else
            {
                return generalMoveNext();
            }

        }

        //requires current to be initialized
        private bool generalMoveNext(){
            bool sub;
            while ( !(sub = current.MoveNext()) && iters.MoveNext() )
            {
                current.Dispose();
                current = iters.Current.GetEnumerator();
            }
            if (sub) return true;
            else return false;
        }

        public void Reset()
        {
            iters.Reset();
            firstMove = true;
        }

        object System.Collections.IEnumerator.Current
        {
            get { return Current; }
        }
    }
}
